/*
 * $Id: LoggerManager.java 164 2013-01-29 11:12:04Z vladimirow@mail.ru $
 * $HeadURL: http://ultralog.googlecode.com/svn/ultralog/tags/release-0.1/src/java/com/google/code/ultralog/LoggerManager.java $
 *
 * This file is a part of ultralog project (http://code.google.com/p/ultralog/).
 * Released under New BSD License.
 */
package com.google.code.ultralog;

import com.google.code.ultralog.configuration.LoggerConfiguration;
import com.google.code.ultralog.configuration.LoggerConfigurationProvider;
import com.google.code.ultralog.configuration.SimpleLoggerConfiguration;
import com.google.code.ultralog.configuration.SimpleLoggerConfigurationProvider;
import com.google.code.ultralog.factory.GeneratingLoggerFactory;
import com.google.code.ultralog.factory.LoggerFactory;
import com.google.code.ultralog.formatter.gfree.GarbageFreeFormatterFactory;
import com.google.code.ultralog.template.TemplateUtils;
import com.google.code.ultralog.writer.CharacterOutputStreamLogRecordWriter;
import com.google.code.ultralog.writer.GarbageFreeOutputStreamWriter;
import com.google.code.ultralog.writer.TemplateLogRecordFormatter;
import com.google.code.ultralog.writer.WriterCharacterOutputStream;

/**
 * Creates and manages loggers using given logger factory and logging
 * configuration provider.
 *
 * @author Mikhail Vladimirov
 */
public class LoggerManager {
    private static LoggerConfigurationProvider configurationProvider =
        new SimpleLoggerConfigurationProvider (
            new SimpleLoggerConfiguration (
                Integer.MIN_VALUE,
                new CharacterOutputStreamLogRecordWriter (
                    new WriterCharacterOutputStream (
                        new GarbageFreeOutputStreamWriter (System.out)),
                    new TemplateLogRecordFormatter (
                        TemplateUtils.parseTemplate (
                            "${levelName} ${timestamp:T%Y-%m-%d %H:%i:%s.%F} " +
                            "[${threadName}] ${logger}: ${message}\n"),
                        GarbageFreeFormatterFactory.INSTANCE))));

    private final static LoggerFactory loggerFactory =
        new GeneratingLoggerFactory (
            new LoggerConfigurationProvider()
            {
                @Override
                public LoggerConfiguration getConfiguration (String loggerName)
                {
                    return configurationProvider.getConfiguration (loggerName);
                }
            },
            GarbageFreeFormatterFactory.INSTANCE);

    private LoggerManager ()
    {
        throw new Error ("Do not instantiate me");
    }

    /**
     * Set configuration provider to be used by logger manager.
     *
     * @param configurationProvider logger configuration provider to use
     */
    public static void setLoggerConfigurationProvider (
        LoggerConfigurationProvider configurationProvider)
    {
        if (configurationProvider == null)
            throw new IllegalArgumentException (
                "Configuration provider is null");

        LoggerManager.configurationProvider = configurationProvider;
    }

    /**
     * Create logger with given interface.  Name of the logger will be the same
     * as the name of logger interface as returned by {@link Class#getName()}.
     *
     * @param <T> logger interface
     * @param loggerInterface logger interface class object
     * @return logger
     */
    public static <T extends Logger> T createLogger (Class <T> loggerInterface)
    {
        if (loggerInterface == null)
            throw new IllegalArgumentException ("Logger interface is null");

        return createLogger (loggerInterface, loggerInterface.getName ());
    }

    /**
     * Create logger with given interface and name.
     *
     * @param <T> logger interface
     * @param loggerInterface logger interface class object
     * @param loggerName name of the logger
     * @return logger
     */
    public static <T extends Logger> T createLogger (
        Class <T> loggerInterface, String loggerName)
    {
        if (loggerInterface == null)
            throw new IllegalArgumentException ("Logger interface is null");

        if (loggerName == null)
            throw new IllegalArgumentException ("Logger name is null");

        return loggerFactory.createLogger (
            loggerInterface, loggerName);
    }
}
